from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from course.models import CourseModel
from rest_framework import status
from django_redis import get_redis_connection

# drf中有用户校验和权限校验


class CartToOrderViews(APIView):
    permission_classes = [IsAuthenticated, ]
    def get(self, request):
        user_id = request.user.id

        redis = get_redis_connection('cart')
        cart_hash = redis.hgetall(f'cart_{user_id}')

        if len(cart_hash) < 1:
            return Response({'message': '购物车没有数据...'}, status=status.HTTP_204_NO_CONTENT)

        # 获取购物车中的数据
        cart = [(int(key.decode()), int(value.decode())) for key, value in cart_hash.items()]
        # [(1, True), (2, False)]
        # 循环遍历购物车数据，上一行是数据类型，根据value值为True，判断获取对应的key
        course_id_list = [i[0] for i in cart if i[1] == True]
        course_list = CourseModel.objects.filter(id__in=course_id_list, is_deleted=False, is_show=True)
        data = []
        for course in course_list:
            data.append(
                {
                    'id': course.id,
                    'name': course.name,
                    # 获取图片的时候，不会自动添加访问前缀，http:127.0.0.1:8000/uploads/ /course/course/1.png
                    'course_cover': "http://127.0.0.1:8000" + course.course_cover.url,
                    'price': course.price,
                    'discount': course.discount,
                    'course_type': course.course_type,
                    'credit': course.credit,
                    # # 判断当前课程是否选中， cart_hash  cart  1 选中 0 未选中
                    # 'selected': str(course.id).encode() in cart_hash and cart_hash[
                    #     str(course.id).encode()].decode() == '1'
                }
            )
        return Response({'message': '购物车选中商品查询成功', 'cart': data}, status=status.HTTP_200_OK)



class CartViews(APIView):
    permission_classes = [IsAuthenticated, ]

    def post(self, request):
        # 将前端需要添加到购物车中的数据，添加到redis中
        # redis写入数据，redis连接，当前用户
        user_id = request.user.id  # 用户id
        # 从前端传递的参数中获取课程id
        course_id = request.data.get('course_id')
        # 商品选中状态，默认是1   boolean 值  1 true  0 false
        selected = 1

        # 需要判断，课程是否存在，数据库中是否存在课程
        try:
            CourseModel.objects.get(is_deleted=False, is_show=True, id=course_id)

            # 获取redis连接
            redis = get_redis_connection('cart')
            # 添加课程数据，到redis中
            redis.hset(f'cart_{user_id}', course_id, selected)
            # 添加完成后，获取当前用户的商品总数量
            cart_total = redis.hlen(f'cart_{user_id}')
            return Response({'message': '添加购物车成功', 'cart_total': cart_total}, status=status.HTTP_200_OK)
        except CourseModel.DoesNotExist:
            print('添加购物车的课程不存在')
            return Response({'message': '课程不存在，添加购物车失败'}, status=status.HTTP_400_BAD_REQUEST)

        # redis.hset(f'cart_{user_id}', 课程id, 是否选中)
        # return Response()

    def get(self, request):
        # 获取购物车数据
        # 获取redis购物车中的课程id
        user_id = request.user.id
        redis = get_redis_connection('cart')
        cart_hash = redis.hgetall(f'cart_{user_id}')
        if len(cart_hash) < 1:
            return Response({'message': '购物车没有数据...'}, status=status.HTTP_400_BAD_REQUEST)
        # {b'1': b'1', b'2': b'1'}
        # 将redis中获取到的数据，进行转码处理，字典（byte字节）格式数据，转换为（1,1）数据类型
        cart = [(int(key.decode()), int(value.decode())) for key, value in cart_hash.items()]
        # [(1, 1), (2, 1), (3, 1)]

        # 根据课程id，查询课程信息   id存在于cart中，将cart中所有的id获取到，并添加到一个新的列表中
        course_id_list = [i[0] for i in cart]

        # 通过课程id，从数据库中获取课程数量
        # 根据课程id列表，查询数据，  id__in 在非连续的范围
        course_list = CourseModel.objects.filter(is_show=True, is_deleted=False, id__in=course_id_list)

        # 简化数据，并拼接返回
        data = []
        for course in course_list:
            data.append(
                {
                    'id': course.id,
                    'name': course.name,
                    # 获取图片的时候，不会自动添加访问前缀，http:127.0.0.1:8000/uploads/ /course/course/1.png
                    'course_cover': "http://127.0.0.1:8000" + course.course_cover.url,
                    'price': course.price,
                    'discount': course.discount,
                    'course_type': course.course_type,
                    'credit': course.credit,
                    # 判断当前课程是否选中， cart_hash  cart  1 选中 0 未选中
                    'selected': str(course.id).encode() in cart_hash and cart_hash[str(course.id).encode()].decode() == '1'
                }
            )
        return Response({'message': '查询购物车成功', 'data': data}, status=status.HTTP_200_OK)

    def put(self, request):
        # 修改数据   全部
        # 全选与反选
        user_id = request.user.id
        selected = int(request.data.get('selected', True))

        redis = get_redis_connection('cart')
        cart_hash = redis.hgetall(f'cart_{user_id}')
        if len(cart_hash) < 1:
            return Response({'message': '购物车没有数据，请先添加需要购买的课程'}, status=status.HTTP_200_OK)

        # 修改redis中所有课程的选择状态
        # redis.hset(f'cart_{user_id}', 课程id)
        course_id_list = [int(key.decode()) for key in cart_hash]

        # 多次redis操作
        # 开启管道  将redis多个命令，一起打包发送给redis数据库，减少频繁访问的网络通信压力
        pipe = redis.pipeline()
        pipe.multi()

        for i in course_id_list:
            pipe.hset(f'cart_{user_id}', i, selected)
        pipe.execute()
        return Response({'message': '全选状态修改成功....'}, status=status.HTTP_200_OK)

    def patch(self, request):
        # 修改   修改数据的部分
        # 修改购物车中，课程的选中状态
        # 1、获取用户id，获取前端传递的课程id和当前课程状态
        # 2、redis中获取
        # 3、判断、修改数据
        user_id = request.user.id
        course_id = int(request.data.get('course_id', None))
        selected = int(request.data.get('selected', True))

        redis = get_redis_connection('cart')
        # 严谨判断
        try:
            CourseModel.objects.get(id=course_id, is_deleted=False, is_show=True)
            print('课程存在，修改状态代码继续...')
            redis.hset(f'cart_{user_id}', course_id, selected)
            return Response({'message': '状态修改成功'}, status=status.HTTP_200_OK)
        except CourseModel.DoesNotExist:
            print('修改的课程不存在')
            redis.hdel(f'cart_{user_id}', course_id)
            return Response({'message': '当前课程不存在，或者已经下架', 'data': ''}, status=status.HTTP_400_BAD_REQUEST)
